home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 031a / flcpp2.zip / DEMO.CPP next >
C/C++ Source or Header  |  1991-07-18  |  14KB  |  276 lines

  1. /*
  2.  
  3.     demo.cpp
  4.     12-6-90
  5.     FlexList tutorial
  6.  
  7.     Copyright 1990
  8.     John W. Small
  9.     All rights reserved
  10.  
  11.     PSW / Power SoftWare
  12.     P.O. Box 10072
  13.     McLean, Virginia 22102 8072
  14.     (703) 759-3838
  15.  
  16.     This program was written to be compiled with the 
  17.     Turbo C++ compiler under the MS DOS operating 
  18.     system.  To port to another environment rewrite
  19.     PressEnter() to pause for the user and then clear
  20.     the screen.  Rand() should be available in some
  21.     form on your system.  Gets(), used for string input,
  22.     may also have to be replaced.  That should do the
  23.     trick.  I would have used "cin", however it proved
  24.     to be inadequate.  I/O streams are for C++ 2.0.
  25.  
  26. */
  27.  
  28. #include <stdio.h>    // getchar(), gets()
  29. #include <stdlib.h>    // rand()
  30. #include <dos.h>    // int86(): to clear screen
  31.  
  32. #include <iostream.h>    // cout
  33. #include <iomanip.h>    // setw()
  34. #include "flexlist.hpp"
  35.  
  36. int ints[] = { 1,2,3,4,5,6,7,8,9,10 };
  37. int i, r, *rptr, *iptr;
  38. char line[81];
  39.  
  40. int CompareIntegers(void *int1, void *int2)
  41. {
  42.     return (*(int *)int1 - *(int *)int2);
  43. }
  44.  
  45. void PressEnter(char *msg = "\n\nPress 'Enter' to continue ...")
  46. {
  47.     union REGS rgs;
  48.     cout << msg;
  49.     getchar();
  50.     rgs.h.ah = 2;    // gotoxy(1,1);
  51.     rgs.x.dx = 0;
  52.     rgs.h.bh = 0;
  53.     int86(0x10,&rgs,&rgs);
  54.     rgs.h.ah = 9;    // clear screen
  55.     rgs.h.al = ' ';
  56.     rgs.x.bx = 0x0007;
  57.     rgs.x.cx = 80 * 25;   // screen dimensions
  58.     int86(0x10,&rgs,&rgs);
  59. }
  60.  
  61. main()  
  62. {
  63. cout << "\nIt's best to have a printed copy of flexlist.hpp to read along with.";
  64. cout << "\n\nAnytime your C++ application requires a stack, queue, or linked";
  65. cout << "\nlist, simply include <flexlist.hpp>.  Next define your stack, queue,";
  66. cout << "\nor list as a variable of type FlexList.  The FlexList class is";
  67. cout << "\nreally a generic hybrid stack-queue-list-array data structure.";
  68. cout << "\nYour FlexList can be initialized to store any type of data.";
  69. cout << "\n\nFor example:";
  70. cout << "\n\n    FlexList Q(sizeof(int));";
  71. cout << "\n\nIn the above example any type, struct or class, can be used";
  72. cout << "\nin place of int.";
  73. PressEnter();
  74. cout << "\nThe FlexList class has over 30 functions for accessing your list as a stack";
  75. cout << "\nqueue, list, or an array interchangeably!  You can push, pop, insert";
  76. cout << "\ndelete, sort, store, recall, or find, to name but just a few";
  77. cout << "\noperations.  The complement of FlexList methods allows you";
  78. cout << "\nto access your list's data by value (copy) or by reference (pointer),";
  79. cout << "\nas well as to move nodes directly between lists.";
  80. cout << "\n\nConsider the following code segment.";
  81. cout << "\n\n    // Insert 10 random integers into a queue. ";
  82. cout << "\n\n        for (i = 0; i < 10; i++)  {";
  83. cout << "\n            r = rand();";
  84. cout << "\n            cout << setw(7) << r;";
  85. cout << "\n            Q.insQD(&r)    // insert r into queue";
  86. cout << "\n        }";
  87. PressEnter("\n\nPress 'Enter' to execute the above code segment.");
  88. cout << "\n";
  89. FlexList Q(sizeof(r));
  90. for (i = 0; i < 10; i++)  {
  91.     r = rand();
  92.     cout << setw(7) << r;
  93.     Q.insQD(&r);
  94. }
  95. PressEnter();
  96. cout << "\nNext, consider this code segment: ";
  97. cout << "\n\n    int CompareIntegers(void *int1, void *int2)";
  98. cout << "\n    {";
  99. cout << "\n        return (*(int *)int1 - *(int *)int2)";
  100. cout << "\n    }";
  101. cout << "\n\n    // Sort the queue and pop the results.";
  102. cout << "\n\n    Q.sort(FLcomparE(CompareIntegers));";
  103. cout << "\n    while (Q.nextD(&r)) cout << setw(7) << r;";
  104. PressEnter("\n\nPress 'Enter' again to execute this code.");
  105. cout << "\nFirst the random integers again ...\n\n";
  106. while (Q.nextD(&r)) cout << setw(7) << r;
  107. cout << "\n\nAnd the sorted results ...\n\n";
  108. Q.sort(FLcomparE(CompareIntegers));
  109. Q.mkcur();
  110. while (Q.nextD(&r)) cout << setw(7) << r;
  111. cout << "\n\nFlexList methods that perform sorts or searches use a function";
  112. cout << "\npointer to a compare function.  Your compare function";
  113. cout << "\ndecides which fields in your data to compare!";
  114. PressEnter();
  115. cout << "\nMany FlexList methods return void pointers which can be considered";
  116. cout << "\nboolean values indicating the success or failure of the method at";
  117. cout << "\nhand.  When such a method is successful, it returns a pointer to";
  118. cout << "\nyour data in the FlexNode in focus.  In the last example 'nextD()'";
  119. cout << "\nwas used to read across the queue.  Its return value is a void";
  120. cout << "\npointer.  After the last FlexNode in the queue, 0 was returned";
  121. cout << "\nthereby terminating the loop.  Let's read across that queue again";
  122. cout << "\nbut this time using pointers to the data instead of copying them.";
  123. cout << "\n\n    int *rptr;";
  124. cout << "\n    while ((rptr = (int *) Q.nextD()) != 0) cout << setw(7) << *rptr;\n\n";
  125. while ((rptr = (int *) Q.nextD()) != 0) cout << setw(7) << *rptr;
  126. PressEnter();
  127. cout << "\nWhen accessing/modifying FlexNodes containing large data structures";
  128. cout << "\nthis approach will usually prove vastly more efficient than copying";
  129. cout << "\nthe data of each node twice.  It's important also to notice that the";
  130. cout << "\nnextD() declaration provides a default for its one parameter thus";
  131. cout << "\nallowing its invocation without an actual parameter.  With methods";
  132. cout << "\nthat copy data to/from FlexNodes, an address of 0 will prevent";
  133. cout << "\nthe method in question from copying data.  The method will carry";
  134. cout << "\nout its operation otherwise unchanged, however.  NextD()'s default";
  135. cout << "\nis zero, so it didn't copy any data, but it still advanced to the";
  136. cout << "\nnext FlexNode and returned a pointer to its data.";
  137. PressEnter();
  138. cout << "\nThe FlexList methods ending in 'N' operate on FlexNodes instead of";
  139. cout << "\nthe data in the nodes.  These come in handy when you are writing queuing";
  140. cout << "\nnetwork simulations and the like, where you want to be constantly moving";
  141. cout << "\nnodes between queues.  A multitasking OS simulation is a good example";
  142. cout << "\nwhere you move PCBs (process control blocks) between the run, ready,";
  143. cout << "\nblocked, and swapped out queues.  Let's see, that last queue with 10";
  144. cout << "\nintegers is still in memory, we'll work on that one.  Consider the";
  145. cout << "\nfollowing code ...";
  146. cout << "\n\n    FlexList S(Q.SizeofNodeData())";
  147. cout << "\n    while (S.pushN(Q.popN()));";
  148. cout << "\n    while (S.prev(&r)) cout << setw(7) << r;";
  149. cout << "\n\nAnd the results ...\n\n";
  150. FlexList S(Q.SizeofNodeData());
  151. while (Q.Nodes()) S.pushN(Q.popN());
  152. while (S.prevD(&r)) cout << setw(7) << r;
  153. Q.clear();
  154. cout << "\n\nWow! We popped one stack into the other.  That should have reversed the";
  155. cout << "\norder.  But wait, we then read the list backward with the prevD() method.";
  156. cout << "\nThat's right, everything's okay.";
  157. PressEnter();
  158. cout << "\nIf you were really watching closely during the last few examples, you";
  159. cout << "\nprobably wondered about how prevD() and nextD() knew where in the list";
  160. cout << "\nthey were.  All FlexLists maintain a pointer to the current node.  Stack";
  161. cout << "\nand queue methods don't disturb this setting.  If the current is popped,";
  162. cout << "\nhowever, the current node becomes undefined just as it is after FlexList";
  163. cout << "\ninitialization.  NextD() and prevD() 'walk' the current pointer across the";
  164. cout << "\nlist, making the current become undefined once each cycle at which time";
  165. cout << "\nthese methods return 0.  This is how I was able to control looping ";
  166. cout << "\nthrough the lists in the previous examples.  Array access methods, i.e.";
  167. cout << "\nstoreD and recallD, set the current pointer to the last node accessed.";
  168. cout << "\nThe next array access first determines whether the front, current, or";
  169. cout << "\nrear pointer is closest to the requested node and then traverses from";
  170. cout << "\nthe closest pointer across the links to the requested node, making it the";
  171. cout << "\nnew current node.  Both methods call the mkcur() method to perform this";
  172. cout << "\noperation.  The insD() method inserts after the current node making the";
  173. cout << "\nnew node current, while delD(), deletes the current node making the";
  174. cout << "\nprevious node current.";
  175. PressEnter();
  176. cout << "\nLet's take a look at a FlexList's array access methods.  You will";
  177. cout << "\nrecall that the S stack of integers is still in memory.";
  178. cout << "\nThe following code will now be executed:";
  179. cout << "\n\n    for(i = 1; S.recallD(&r,i); i++)";
  180. cout << "\n        cout << setw(7) << r;";
  181. cout << "\n\nAnd the results ...\n\n";
  182. for (i = 1; S.recallD(&r,i); i++)
  183.     cout << setw(7) << r;
  184. S.clear();
  185. PressEnter();
  186. cout << "\nLet's see insD() and delD() in action and this time with something other";
  187. cout << "\nthan integers!  Consider the following code and then start your input.";
  188. cout << "\n\n    char line[81];";
  189. cout << "\n    FlexList s(FLstrings);";
  190. cout << "\n    while (s.Nodes() < 3)  {";
  191. cout << "\n        cout << \"\\nEnter string: \"; gets(line);";
  192. cout << "\n        s.insD(line);";
  193. cout << "\n    }\n\n";
  194. FlexList s(FLstrings);
  195. while (s.Nodes() < 3)  {
  196.     cout << "Enter string: "; 
  197.     gets(line);
  198.     s.insD(line);
  199. }
  200. PressEnter();
  201. cout << "\n\nThe last node is now the current one and we'll start deleting them.";
  202. cout << "\nSince deleting makes the previous node the new current node, successive";
  203. cout << "\ndeletes will walk across the list from the rear to the front.";
  204. cout << "\nThe following code will now be executed.";
  205. cout << "\n\n    while (s.delD(line)) cout << \"\\n\" << line;\n";
  206. while (s.delD(line)) cout << "\n" << line;
  207. cout << "\n\nThis FlexList of strings is an example of a heterogeneous FlexList.";
  208. cout << "\nThe FlexNodes were only as big as the strings held within.";
  209. cout << "\nSee the first FlexList constructor entry in the reference chapter for";
  210. cout << "\ninformation on deriving your own heterogeneous FlexLists.";
  211. cout << "\nFlexlist.cpp's comments also explain what is going on.";
  212. PressEnter();
  213. cout << "\nSometimes you want to work with a list, other times it's more convenient";
  214. cout << "\nto work with an array.  Although Flexlist allows this chameleon behavior,";
  215. cout << "\nyour application may progress in stages that favor a list at one point";
  216. cout << "\nand an array at another.  FlexList has methods for converting a";
  217. cout << "\nconventional array into a FlexList or a FlexList into a dynamic array";
  218. cout << "\nthus allowing you to optimize the performance of your application.";
  219. cout << "\nYou can think of the FlexList constructor with array parameters, as";
  220. cout << "\nexploding a conventional array into a FlexList.  For example:";
  221. cout << "\n\n    int ints[] = { 1,2,3,4,5,6,7,8,9,10 };";
  222. cout << "\n    FlexList A(sizeof(int),10,ints);";
  223. cout << "\n    while (A.nextD(&i)) cout << setw(7) << i;";
  224. cout << "\n\nAnd the results of its execution ...\n\n";
  225. FlexList A(sizeof(int),10,ints);
  226. while (A.nextD(&i)) cout << setw(7) << i;
  227. PressEnter();
  228. cout << "\nThink of the FlexList method, pack(), as imploding a FlexList into a";
  229. cout << "\ndynamic array.  Consider the following code and the previous list.";
  230. cout << "\n\n    int *iptr = A.pack();";
  231. cout << "\n    for (i = 0; i < 10; i++)";
  232. cout << "\n        cout << setw(7) << iptr[i];";
  233. cout << "\n\nAnd the results of its execution ...\n\n";
  234. iptr = (int *) A.pack();
  235. for (i = 0; i < 10; i++)
  236.     cout << setw(7) << iptr[i];
  237. delete iptr; A.clear();
  238. cout << "\n\nThe FlexList method, packPtrs, simply creates a 0 terminated array of";
  239. cout << "\npacked pointers which point to the data areas of all the FlexNodes.";
  240. cout << "\nDo you remember how FlexList methods returning void pointers worked?";
  241. cout << "\nThese are the same pointers all packed into a dynamic array.  You can";
  242. cout << "\nquickly zip around a FlexList's nodes using these pointers to modify data.";
  243. cout << "\nWhen your application is finished this phase of processing it discards";
  244. cout << "\nthe array of pointers.";
  245. PressEnter();
  246. cout << "\nSince FlexList is a class, you can derive your own classes from it.";
  247. cout << "\nWhy would you want too?  Suppose that you need a place to store data";
  248. cout << "\npertaining to the whole list?  You can declare a new class, derived";
  249. cout << "\nfrom FlexList, that contains variables for this data.  Thus you can";
  250. cout << "\nstore data associated with the list, in the list!  Derived classes can";
  251. cout << "\nalso be made to store heterogeneous data in the FlexNodes via a";
  252. cout << "\nFlexList's virtual function hooks.  These virtual functions are defined";
  253. cout << "\nthe FlexList base class to handle strings as you saw previously.  Any-";
  254. cout << "\ntime a FlexList is constructed for data the size of zero the virtual";
  255. cout << "\nfunctions are turned on to create and destroy FlexNodes as well as";
  256. cout << "\ncopying the variant length data.";
  257. cout << "\n\nYour application's code size won't continue to grow when you add new";
  258. cout << "\ntypes of lists either, since FlexList is generic, it is able to store";
  259. cout << "\nany type of data, struct or class.  And with the virtual overide feature";
  260. cout << "\nenabled in derived classes, almost any type of heterogeneous data can be";
  261. cout << "\naccommodated.  Since FlexLists are initialized at";
  262. cout << "\nrun time, the data they hold or even their creation can be specified";
  263. cout << "\nat run time thus allowing your application new dimensions of adaptibility";
  264. cout << "\nto user specifications.  And with FlexList you can quickly construct";
  265. cout << "\nlists of lists or other composite structures.  FlexList will save you";
  266. cout << "\nhours of coding time, code space, money and headaches!";
  267. PressEnter();
  268. cout << "\n\nCopyright 1990, John W. Small, All right reserved";
  269. cout << "\n\nPSW / Power SoftWare";
  270. cout << "\nP.O. Box 10072";
  271. cout << "\nMcLean, Virginia 22102 8072";
  272. cout << "\n(703) 759-3838";
  273. cout << "\n\nRegister FlexList for $79.95 and get the";
  274. cout << "\ncomplete picture.";
  275. }
  276.